/*
* Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/&gt;.
*
*/

#include "calendarbutton.h"
#include <QStylePainter>
#include <QStyleOptionButton>
#include <QApplication>
#include "kysdk/applications/windowmanager/windowmanager.h"


#define ORG_UKUI_STYLE            "org.ukui.style"
#define STYLE_NAME                "styleName"

#define HOUR_SYSTEM_CONTROL "org.ukui.control-center.panel.plugins"

#define DATA_FORMAT     "date"          //日期格式：yyyy/MM/dd、yyyy-MM-dd
#define TIME_FORMAT     "hoursystem"    //时间格式：12小时制、24小时制
#define WEEK_FORMAT     "firstday"      //一周第一天：星期一、星期日
#define CALENDAR_FORMAT "calendar"      //日历格式：公历-solarlunar、农历-lunar
#define HOUR_SYSTEM_24_Vertical     "hh:mm ddd  yyyy/MM/dd"
#define HOUR_SYSTEM_12_Horizontal   "Ahh:mm ddd  yyyy/MM/dd"

#define SYSTEM_FONT_SET  "org.ukui.style"
#define SYSTEM_FONT_SIZE "systemFontSize"
#define SYSTEM_FONT      "systemFont"

#define CALENDAR_BUTTON_WIDTH  120

#define KYSDK_TIMERSERVER "com.kylin.kysdk.TimeServer"
#define KYSDK_TIMERPATH "/com/kylin/kysdk/Timer"
#define KYSDK_TIMERINTERFACE "com.kylin.kysdk.TimeInterface"

#define  UKUI_CONTROL_CENTER_SERVER     "org.freedesktop.Accounts"
#define  UKUI_CONTROL_CENTER_PATH       "/org/freedesktop/Accounts/User1000"
#define  UKUI_CONTROL_CENTER_INTERFACE  "org.freedesktop.Accounts.User"
#define  PROPERTIES_NAME                "FormatsLocale"
#define  US_FORMATS                        "en_US.UTF-8"
#define  ZH_CN_FORMATS                     "zh_CN.UTF-8"
#define  BO_CN_FORMATS                     "bo_CN.UTF-8"  //藏文

#define PANEL_SIZE_LARGE  92
#define PANEL_SIZE_MEDIUM 70
#define PANEL_SIZE_SMALL  46
#define PANEL_SIZE_KEY    "panelsize"

CalendarButton::CalendarButton(IUKUIPanelPlugin *plugin, QWidget *parent):
    QPushButton(parent),
    m_parent(parent),
    m_plugin(plugin)
{
    //设置按钮样式和属性
    this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    this->setFlat(true);
    /*按钮边距固定0px，尽可能多显示日期信息。CalendarButton不继承ToolButton的原因就是
    主题框架提供的ToolButton的边距是固定值，无法修改*/
    this->setStyleSheet("padding: 0px;}");
    const QByteArray id(ORG_UKUI_STYLE);
    if (QGSettings::isSchemaInstalled(id)) {
        m_styleGsettings = new QGSettings(id);
        connect(m_styleGsettings, &QGSettings::changed, this, [=] (const QString &key) {
            if (key==STYLE_NAME) {
                update();
            }
        });
    }
    this->setToolTip(tr("Time and Date"));

    //初始化时间日期格式相关Gsettings
    initTimeGsettings();

    //初始化系统字体相关Gsetting
    initFontGsettings();

    //使用系统提供的sdk刷新时间显示
    QDBusConnection::systemBus().connect(KYSDK_TIMERSERVER,
                                         KYSDK_TIMERPATH,
                                         KYSDK_TIMERINTERFACE,
                                         "TimeSignal",
                                         this,
                                         SLOT(updateBtnText(QString))
                                         );
    QDBusConnection::systemBus().connect(KYSDK_TIMERSERVER,
                                         KYSDK_TIMERPATH,
                                         KYSDK_TIMERINTERFACE,
                                         "TimeChangeSignal",
                                         this,
                                         SLOT(updateBtnText(QString))
                                         );

    m_listenGsettings = new ListenGsettings();
    QObject::connect(m_listenGsettings,&ListenGsettings::iconsizechanged,[this]{updateBtnText(QString());});
    QObject::connect(m_listenGsettings,&ListenGsettings::panelpositionchanged,[this]{updateBtnText(QString());});

    //更新日历按钮内容
    updateBtnText(QString());
}

CalendarButton::~CalendarButton()
{
    if(m_styleGsettings) {
        m_styleGsettings->deleteLater();
    }
    if(m_timeGsettings) {
        m_timeGsettings->deleteLater();
    }
    if(m_fontGsettings) {
        m_fontGsettings->deleteLater();
    }
    if(m_listenGsettings) {
        m_listenGsettings->deleteLater();
    }
}

void CalendarButton::contextMenuEvent(QContextMenuEvent *event)
{
    m_menuCalender = new QMenu(this);
    m_menuCalender->setAttribute(Qt::WA_DeleteOnClose);
    m_menuCalender->setGeometry(m_plugin->panel()->calculatePopupWindowPos
                              (mapToGlobal(event->pos()),
                               m_menuCalender->sizeHint()));
    m_menuCalender->addAction(QIcon::fromTheme("document-page-setup-symbolic"),
                   tr("Time and Date Setting"),
                   this, SLOT(setControlTime()));
    m_menuCalender->show();
    kdk::WindowManager::setGeometry(m_menuCalender->windowHandle(),
                                        m_plugin->panel()->calculatePopupWindowPos(mapToGlobal(event->pos()), m_menuCalender->sizeHint()));
}

void CalendarButton::mousePressEvent(QMouseEvent *event)
{
    if (Qt::LeftButton == event->button()){
        Q_EMIT pressShowHideCalendar();
    }
}

//初始化时间日期格式相关Gsettings
void CalendarButton::initTimeGsettings()
{
    const QByteArray id(HOUR_SYSTEM_CONTROL);
    if (QGSettings::isSchemaInstalled(id)) {
        m_timeGsettings = new QGSettings(id);
        connect(m_timeGsettings, &QGSettings::changed, this, [=] (const QString &key) {
            if (key == DATA_FORMAT) {
                m_dataFormat = m_timeGsettings->get(DATA_FORMAT).toString();
            } else if(key == TIME_FORMAT) {
                m_timeFormat = m_timeGsettings->get(TIME_FORMAT).toString();
            } else if(key == WEEK_FORMAT) {
                m_weekFormat = m_timeGsettings->get(WEEK_FORMAT).toString();
            } else if(key == CALENDAR_FORMAT) {
                m_calendarFormat = m_timeGsettings->get(CALENDAR_FORMAT).toString();
            }
            updateBtnText(QString());
        });

        QStringList ketList = m_timeGsettings->keys();
        if(ketList.contains(DATA_FORMAT))
            m_dataFormat = m_timeGsettings->get(DATA_FORMAT).toString();
        if(ketList.contains(TIME_FORMAT))
            m_timeFormat = m_timeGsettings->get(TIME_FORMAT).toString();
        if(ketList.contains(WEEK_FORMAT))
            m_weekFormat = m_timeGsettings->get(WEEK_FORMAT).toString();
        if(ketList.contains(CALENDAR_FORMAT))
            m_calendarFormat = m_timeGsettings->get(CALENDAR_FORMAT).toString();
    }
}

//初始化系统字体相关Gsetting
void CalendarButton::initFontGsettings()
{
    const QByteArray id(SYSTEM_FONT_SET);
    if (QGSettings::isSchemaInstalled(id)) {
        m_fontGsettings = new QGSettings(id);
        connect(m_fontGsettings, &QGSettings::changed, this, [=] (const QString &keys){
            if(keys == SYSTEM_FONT_SIZE || keys == SYSTEM_FONT){
                m_systemFontSize = m_fontGsettings->get(SYSTEM_FONT_SIZE).toString();
                m_systemFont = m_fontGsettings->get(SYSTEM_FONT).toString();
                updateBtnText(QString());
            }
        });

        QStringList ketList = m_fontGsettings->keys();
        if(ketList.contains(SYSTEM_FONT_SIZE))
            m_systemFontSize = m_fontGsettings->get(SYSTEM_FONT_SIZE).toString();
        if(ketList.contains(SYSTEM_FONT))
            m_systemFont = m_fontGsettings->get(SYSTEM_FONT).toString();
    }
}

//右键跳转到控制面板日期页面
void CalendarButton::setControlTime()
{
    QProcess *process =new QProcess(this);
    process->start(
            "bash",
            QStringList() << "-c"
                          << "dpkg -l | grep ukui-control-center");
    process->waitForFinished();
    QString strResult = process->readAllStandardOutput() + process->readAllStandardError();
    if (-1 != strResult.indexOf("3.0")) {
        QProcess::startDetached(QString("ukui-control-center -t"));
    } else {
        QProcess::startDetached(QString("ukui-control-center -m Date"));
    }
}

/*
 * 更新时间文字显示
 * 横向任务栏显示格式(中文)：
 *      24小时制：
 *              hh:mm ddd
 *              yyyy/MM/dd
 *      12小时制：
 *              AM hh:mm ddd
 *              yyyy/MM/dd
 *
 * 纵向任务栏显示格式:
 *      24小时制：
 *              hh:mm        或   hh:mm
 *               ddd               ddd
 *              yyyy/MM/dd        MM/dd
 *      12小时制：
 *               AM                  AM
 *              hh:mm               hh:mm
 *               ddd          或     ddd
 *              yyyy/MM/dd          MM/dd
*/
void CalendarButton::updateBtnText(QString timerStr)
{
    Q_UNUSED(timerStr);
    QString formatsLocale = getFormatsLocale();
    QString displayText;
    CalendarButtonText *m_btnText;
    if(formatsLocale == ZH_CN_FORMATS) {
        m_btnText = new ZhCnText(m_plugin,this);
    } else if(formatsLocale == US_FORMATS) {
        m_btnText = new EnUsText(m_plugin,this);
    } else {
        m_btnText = new OtherLanguagText(m_plugin,this);
    }
    displayText = m_btnText->getBtnText();
    m_btnText->deleteLater();
    this->setText(displayText);
}

/* 获取时间、日期、货币格式 */
QString CalendarButton::getFormatsLocale()
{
    QDBusInterface interface(UKUI_CONTROL_CENTER_SERVER,
                             UKUI_CONTROL_CENTER_PATH,
                             UKUI_CONTROL_CENTER_INTERFACE,
                             QDBusConnection::systemBus());
    QVariant ret = interface.property(PROPERTIES_NAME);
    return ret.toString();
}

void CalendarButton::paintEvent(QPaintEvent* event)
{
    QStylePainter painter(this);
    QStyleOptionButton option;
    initStyleOption(&option);
    if ((option.state & QStyle::State_Enabled) &&
            (option.state & QStyle::State_MouseOver ||
             option.state & QStyle::State_HasFocus)) {
        painter.save();
        painter.setPen(Qt::NoPen);

        QPalette pal = qApp->palette();
        QColor color = pal.color(QPalette::Active, QPalette::BrightText);
        color.setAlphaF(m_btnAlphaF);
        painter.setBrush(color);
        painter.setRenderHint(QPainter::Antialiasing);

        painter.drawRoundedRect(option.rect, 6, 6);
        painter.restore();
    }

    QStyleOptionButton subopt = option;
    subopt.rect = painter.style()->subElementRect(QStyle::SE_PushButtonContents, &option, this);
    subopt.palette.setBrush(QPalette::BrightText, subopt.palette.brightText());
    painter.style()->drawControl(QStyle::CE_PushButtonLabel, &subopt, &painter, this);
    return;
}
